package com.xiaoruyuan.firstday.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据源配置类
 *
 * @author sunfeng
 */
@Configuration
public class DruidDataSourceConfig {

  @Value("${spring.datasource.url}")
  private String dbUrl;
  @Value("${spring.datasource.username}")
  private String username;
  @Value("${spring.datasource.password}")
  private String password;
  @Value("${spring.datasource.driverClassName}")
  private String driverClassName;
  @Value("${spring.datasource.initialSize}")
  private int initialSize;
  @Value("${spring.datasource.minIdle}")
  private int minIdle;
  @Value("${spring.datasource.maxActive}")
  private int maxActive;
  @Value("${spring.datasource.maxWait}")
  private int maxWait;
  @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
  private int timeBetweenEvictionRunsMillis;
  @Value("${spring.datasource.minEvictableIdleTimeMillis}")
  private int minEvictableIdleTimeMillis;
  @Value("${spring.datasource.validationQuery}")
  private String validationQuery;
  @Value("${spring.datasource.testWhileIdle}")
  private boolean testWhileIdle;
  @Value("${spring.datasource.testOnBorrow}")
  private boolean testOnBorrow;
  @Value("${spring.datasource.testOnReturn}")
  private boolean testOnReturn;
  @Value("${spring.datasource.poolPreparedStatements}")
  private boolean poolPreparedStatements;
  @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
  private int maxPoolPreparedStatementPerConnectionSize;
  @Value("${spring.datasource.filters}")
  private String filters;
  @Value("{spring.datasource.connectionProperties}")
  private String connectionProperties;

  @Bean
  @Primary
  public DataSource dataSource() {
    DruidDataSource datasource = new DruidDataSource();
    datasource.setUrl(this.dbUrl);
    datasource.setUsername(username);
    datasource.setPassword(password);
    datasource.setDriverClassName(driverClassName);
    datasource.setInitialSize(initialSize);
    datasource.setMinIdle(minIdle);
    datasource.setMaxActive(maxActive);
    datasource.setMaxWait(maxWait);
    datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
    datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
    datasource.setValidationQuery(validationQuery);
    datasource.setTestWhileIdle(testWhileIdle);
    datasource.setTestOnBorrow(testOnBorrow);
    datasource.setTestOnReturn(testOnReturn);
    datasource.setPoolPreparedStatements(poolPreparedStatements);
    datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);

    try {
      datasource.setFilters(filters);
    } catch (SQLException e) {
      e.printStackTrace();
    }

    // 设置允许执行批量语句，针对Druid数据源，关闭掉防火墙的拦截
    WallConfig wallConfig = new WallConfig();
    // 允许一次执行多条语句
    wallConfig.setMultiStatementAllow(true);
    // 允许一次执行多条语句
    wallConfig.setNoneBaseStatementAllow(true);
    WallFilter wallFilter = new WallFilter();
    wallFilter.setConfig(wallConfig);
    List<Filter> filters = new ArrayList<>();
    filters.add(wallFilter);
    datasource.setProxyFilters(filters);

    datasource.setConnectionProperties(connectionProperties);

    return datasource;
  }
}